

<template>
  <div
    ref="container"
    :class="props.className"
    :style="{ width: props.width, height: props.height }"
  ></div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts'


const props = defineProps({
  option: {
    type: Object,
    require: true,
  }, //配置项
  width: {
    type: String,
    default: '300px',
  },
  height: {
    type: String,
    default: '200px',
  },
  className: {
    type: String,
    default: 'cl-chartCom',
  },
  loading: {
    type: Boolean,
    default: false,
  },
  onClick: {
    type: Function,
  },
})

const container = ref() // 容器元素
const instance = shallowRef() // 实例
const resizeObserver = shallowRef() // 元素尺寸侦听器
const debounceTimer = ref() //防抖计时器id


// 初始化
const init = () => {
  if (!container.value) return

  //查看容器上是否已经挂载了echarts实例 , 如果已挂载就获取并使用该实例,如果未挂载就进行初始化
  instance.value = echarts.getInstanceByDom(container.value)
  if (!instance.value) {
    instance.value = echarts.init(container.value)
  }

  // 绘制图表
  draw()
  // 侦听图表事件
  addListeningChartEvent()
}
// 绘制图表
const draw = () => {
  if (!props.option || !instance.value) return
  instance.value.setOption(props.option, {
    notMerge: true,
  })
}

// 图表自适应
// 重置图表尺寸
const resize = () => {
  clearTimeout(debounceTimer.value)
  debounceTimer.value = setTimeout(() => {
    instance.value?.resize({
      animation: {
        duration: 300,
      },
    })
    debounceTimer.value = null
  }, 300)
}
resizeObserver.value = new ResizeObserver(resize)

// 重绘图表
watch(props, () => {
  nextTick(() => {
    draw()
  })
})

// loading动画
watchEffect(() => {
  props.loading ? instance.value?.showLoading() : instance.value?.hideLoading()
})

// echarts事件绑定
const addListeningChartEvent = () => {
  // 点击事件
  props.onClick &&
    instance.value?.on('click', 'series', (e: any) => {
      if (typeof props.onClick !== 'undefined') {
        props.onClick(e, instance.value, props.option)
      }

    })
}

onMounted(() => {
  nextTick(() => {
    init()
    resizeObserver.value.observe(container.value)
  })
})
onUnmounted(() => {
  instance.value?.dispose()
  resizeObserver.value?.disconnect()
  resizeObserver.value = null
  clearTimeout(debounceTimer.value)
  debounceTimer.value = null
})

</script>

<style scoped lang="scss"></style>